<template>
  <div class="editTable" ref="editTableBox">
    <div class="edit-table-toolbar">
      <div class="edit-table-toolbar__title">{{ title }}</div>
      <div class="edit-btn" v-if="!hideBtn">
        <slot name="btnsBefore"></slot>
        <template v-for="(i, index) in btnConfig">
          <el-button
            size="mini"
            :key="index"
            v-if="showBtn(i.name)"
            :type="i.type"
            :icon="i.icon"
            @click="i.methons"
            >{{ i.text }}</el-button
          >
        </template>
        <slot name="btnsAfter"></slot>
      </div>
    </div>
    <div class="edit-table-content">
      <el-form
        ref="formTable"
        :model="tableConfig"
        :rules="rules"
        label-width="0px"
      >
        <el-table
          :data="tableConfig.data"
          :span-method="arraySpanMethod"
          border
          stripe
          highlight-current-row
          ref="editTable"
          :header-cell-style="headerStyle"
          :height="tableConfig.height"
          :max-height="tableConfig.maxHeight"
        >
          <el-table-column
            v-if="tableConfig.showCheckbox"
            type="selection"
            fixed="left"
            align="center"
            width="55"
          ></el-table-column>
          <el-table-column
            v-if="tableConfig.showIndex"
            type="index"
            width="55"
            label="序号"
            align="center"
          ></el-table-column>
          <template v-for="(item, index) in tableConfig.column">
            <el-table-column
              v-if="!item.isHide"
              :label="item.label"
              :width="item.width"
              align="center"
              :min-width="item.minWidth"
              :prop="item.prop"
              :key="index"
            >
              <template slot-scope="scope">
                <el-form-item
                  :prop="'data.' + scope.$index + '.' + scope.column.property"
                  :rules="rules[item.prop]"
                >
                  <slot
                    :name="item.prop"
                    :item="item"
                    :editFormInfo="scope.row"
                  >
                    <template v-if="scope.row.editable">
                      <el-select
                        v-model="scope.row[scope.column.property]"
                        v-if="item.type === 'select'"
                        :multiple="item.multiple"
                        :disabled="item.disabled"
                        @change="
                          (val) =>
                            changeSelete(
                              val,
                              item.text,
                              scope.$index,
                              item.seleteOption
                            )
                        "
                        size="mini"
                        class="w100"
                      >
                        <template v-for="item_s in item.seleteOption">
                          <el-option
                            v-if="
                              typeof scope.row[scope.column.property] ==
                              'string'
                            "
                            :key="item_s.value"
                            :label="item_s.label"
                            :disabled="
                              item.hasOwnProperty('disabledOp') &&
                              item.disabledOp(item_s.value, tableConfig.data)
                            "
                            :value="'' + item_s.value"
                          ></el-option>
                          <el-option
                            v-else-if="
                              typeof scope.row[scope.column.property] ==
                              'number'
                            "
                            :key="item_s.value"
                            :label="item_s.label"
                            :disabled="
                              item.hasOwnProperty('disabledOp') &&
                              item.disabledOp(item_s.value, tableConfig.data)
                            "
                            :value="
                              ('' + item_s.value).trim() == ''
                                ? ''
                                : parseInt(item_s.value)
                            "
                          ></el-option>
                          <el-option
                            v-else
                            :key="item_s.value"
                            :label="item_s.label"
                            :disabled="
                              item.hasOwnProperty('disabledOp') &&
                              item.disabledOp(item_s.value, tableConfig.data)
                            "
                            :value="item_s.value"
                          ></el-option>
                        </template>
                      </el-select>

                      <el-checkbox
                        v-model="scope.row[scope.column.property]"
                        v-else-if="item.type === 'checkbox'"
                        :true-label="1"
                        :false-label="0"
                        @change="
                          item.method ? item.method(scope.row, item) : ''
                        "
                        :disabled="item.disabled"
                      ></el-checkbox>
                      <span v-else-if="item.type === 'disableText'">{{
                        scope.row[scope.column.property]
                      }}</span>
                      <el-date-picker
                        v-else-if="
                          [
                            'date',
                            'week',
                            'month',
                            'week',
                            'year',
                            'datetime',
                            'daterange',
                            'datetimerange',
                          ].includes(item.type)
                        "
                        v-model="scope.row[scope.column.property]"
                        :title="scope.row[scope.column.property]"
                        class="w100"
                        :type="item.type"
                        range-separator="至"
                        start-placeholder="开始日期"
                        end-placeholder="结束日期"
                        :disabled="item.disabled"
                        :format="dateFrm(item.type)"
                        :value-format="dateFrm(item.type)"
                        size="mini"
                        placeholder="选择日期"
                      ></el-date-picker>
                      <el-input
                        v-else-if="item.type === 'dept'"
                        :key="scope.$index"
                        size="mini"
                        type="textarea"
                        rows="2"
                        @click.native="
                          getOrgInfo(
                            scope.$index,
                            scope.row[scope.column.property],
                            item
                          )
                        "
                        v-model="scope.row[scope.column.property]"
                        :title="scope.row[scope.column.property]"
                        readonly
                        class="w100"
                      ></el-input>
                      <el-input
                        v-else-if="item.type === 'number'"
                        :key="scope.$index"
                        size="mini"
                        :readonly="item.readonly"
                        :disabled="item.disabled"
                        :type="item.type || ''"
                        @change="item.method ? item.method(scope.row) : ''"
                        v-model="scope.row[scope.column.property]"
                        :title="scope.row[scope.column.property]"
                        @wheel.native.prevent="stopScrollFun($event, item.type)"
                        class="w100"
                      ></el-input>
                      <el-button
                        type="text"
                        size="small"
                        v-else-if="item.type == 'textButton'"
                        @click="
                          item.buttonMethod
                            ? item.buttonMethod(scope.$index, scope.row)
                            : null
                        "
                        >{{ scope.row[scope.column.property] }}</el-button
                      >
                      <el-input
                        v-else
                        placeholder="请输入"
                        :key="scope.$index"
                        size="mini"
                        :readonly="item.readonly"
                        :disabled="item.disabled"
                        :type="item.type || ''"
                        :rows="item.rows || 1"
                        @change="
                          item.method
                            ? item.method(scope.row, scope.$index)
                            : ''
                        "
                        v-model="scope.row[scope.column.property]"
                        :title="scope.row[scope.column.property]"
                        class="w100"
                      ></el-input>
                    </template>
                    <template v-else>
                      <el-button
                        type="text"
                        size="small"
                        v-if="
                          item.scopeType &&
                          item.scopeType == 'textButton' &&
                          (item.isHide ? !item.isHide : true)
                        "
                        @click="
                          item.buttonMethod
                            ? item.buttonMethod(scope.$index, scope.row)
                            : null
                        "
                        >{{ scope.row[scope.column.property] }}</el-button
                      >
                      <el-checkbox
                        v-model="scope.row[scope.column.property]"
                        v-else-if="item.type === 'checkbox'"
                        :true-label="1"
                        :false-label="0"
                        :disabled="item.disabled"
                        class="special"
                      ></el-checkbox>

                      <template v-else>
                        <el-tooltip
                          effect="dark"
                          v-if="item.showTooltip"
                          placement="top"
                          :content="
                            item.formatter
                              ? item.formatter(
                                  scope.row[scope.column.property],
                                  scope.row
                                )
                              : item.text
                              ? formatterNull(scope.row[item.text])
                              : formatterNull(scope.row[scope.column.property])
                          "
                        >
                          <span
                            class="table-cloumn__span--tooltip w100"
                            style="display: inline-block"
                            >{{
                              item.formatter
                                ? item.formatter(
                                    scope.row[scope.column.property],
                                    scope.row
                                  )
                                : item.text
                                ? formatterNull(scope.row[item.text])
                                : formatterNull(
                                    scope.row[scope.column.property]
                                  )
                            }}</span
                          >
                        </el-tooltip>
                        <span v-else>{{
                          item.formatter
                            ? item.formatter(
                                scope.row[scope.column.property],
                                scope.row
                              )
                            : item.text
                            ? formatterNull(scope.row[item.text])
                            : formatterNull(scope.row[scope.column.property])
                        }}</span>
                      </template>
                    </template>
                  </slot>
                </el-form-item>
              </template>
            </el-table-column>
          </template>
        </el-table>
      </el-form>
      <dialogPublic
        :title="'选择组织'"
        :show.sync="show"
        @doSubmit="addSeleteMember"
        @doClose="() => (show = false)"
      >
        <orgMemberSelect
          ref="orgMemberSelect"
          v-if="show"
          :otherInfo="formData"
          :seleteSetting="orgMemberSelect"
        ></orgMemberSelect>
      </dialogPublic>
    </div>
  </div>
</template>
<script>
export default {
  // props: ["tableSetting", "formData", "hideBtn","stripe"],
  props: {
    tableSetting: {
      type: Object,
      default: () => {
        return {};
      },
    },
    formData: {
      type: Object,
      default: () => {
        return {};
      },
    },
    tableData: {
      type: Array,
      default: () => {
        return [];
      },
    },
    hideBtn: {
      type: Boolean,
      default: false,
    },
    stripe: {
      type: Boolean,
      default: false,
    },
    //合并行或列
    arraySpanMethod: Function,
  },
  data() {
    return {
      title: "表格标题",
      tableConfig: {
        select: true,
        data: [],
        column: [],
        showIndex: true, //是否显示序号
        showCheckbox: true, //是否显示复选框
      },
      btnConfig: [
        {
          name: "add",
          text: "新增",
          icon: "el-icon-plus",
          type: "primary",
          methons: () => {
            this.add();
          },
        },
        {
          name: "addOper",
          text: "新增",
          icon: "el-icon-plus",
          methons: () => {
            this.add("oper");
          },
        },
        {
          name: "edit",
          text: "编辑",
          type: "success",
          icon: "el-icon-edit",
          methons: () => {
            this.edit();
          },
        },
        {
          name: "save",
          text: "保存",
          icon: "el-icon-check",
          type: "primary",
          methons: () => {
            this.save();
          },
        },
        {
          name: "delete",
          text: "删除",
          icon: "el-icon-delete",
          type: "primary",
          methons: () => {
            this.delete();
          },
        },
      ],
      btnArr: [],
      //组织树选择人员
      orgMemberSelect: {
        seleteType: "orgmember",
        props: {
          label: "organizationName",
          children: "children",
        },
        chosedData: [],
      },
      show: false,
      deptItem: {},
      rules: {},
    };
  },
  computed: {
    rowProp() {
      let row = new Object();
      this.tableConfig.column.map((i) => {
        row[i.prop] = "";
      });
      return row;
    },
  },

  watch: {
    "tableSetting.maxHeight"() {
      this.tableConfig.maxHeight = this.tableSetting.maxHeight;
    },
    "tableSetting.title"() {
      this.title = this.tableSetting.title;
    },
    "tableConfig.data": {
      handler(val) {
        this.$emit("changeTableData", val);
      },
      deep: true,
    },
    tableData: {
      handler(val) {
        if (val.length > 0) {
          this.setTableData(val);
        }
      },
      deep: true,
    },
  },
  created() {
    this.init();
  },
  mounted() {
    this.setTableHeight();
  },
  methods: {
    init() {
      let {
        btnArr,
        column,
        title,
        showIndex,
        showCheckbox,
        data,
        select,
        maxHeight,
        height,
      } = this.tableSetting;
      this.btnArr = btnArr || [];
      this.title = title || "";
      this.tableConfig.showIndex = showIndex;
      this.tableConfig.showCheckbox = showCheckbox;
      this.tableConfig.column = column || [];
      /* 优先tableData里面的值 */
      let len = this.tableData ? this.tableData.length : 0;
      if (len > 0) {
        this.tableConfig.data = this.tableData;
      } else {
        this.tableConfig.data = data || [];
      }
      this.tableConfig.select = select;
      this.tableConfig.maxHeight = maxHeight;
      this.tableConfig.height = height;
      this.tableConfig.data.map((i, index) => {
        i.rowIndex = index;
      });

      let rules = {};
      this.tableConfig.column.map((i) => {
        if (i.required) {
          rules[i.prop] = [];
          let message = "";
          if (i.type === "text" || i.type === "textarea") {
            message = `请输入`;
          } else {
            message = `请选择`;
          }
          rules[i.prop].push({
            required: true,
            message: message + i.label,
            trigger: i.trigger || "blur",
          });
          if (i.rules) {
            rules[i.prop].push(i.rules);
          }
        }
      });
      this.rules = Object.assign({}, rules);
    },
    headerStyle() {
      return {};
    },
    showBtn(btn) {
      return this.btnArr.indexOf(btn) != -1;
    },
    setTableCellData(name, index, data) {
      this.$set(this.tableConfig.data, index, data);
    },
    //日期数据处理
    dateFrm(type) {
      if (type === "date" || type === "daterange") {
        return "yyyy-MM-dd";
      } else if (type == "datetime" || type === "datetimerange") {
        return "yyyy-MM-dd HH:mm:ss";
      } else if (type == "month") {
        return "yyyy-MM";
      } else if (type == "year") {
        return "yyyy";
      } else {
        return "";
      }
    },
    //点击新增
    add() {
      let len = this.tableConfig.data.length;
      let rowIndex = 0;
      if (len) {
        rowIndex = this.tableConfig.data[len - 1].rowIndex + 1;
      }
      let nRow = Object.assign(
        {},
        { rowIndex: rowIndex, editable: true },
        this.rowProp
      );

      if (this.tableSetting.addMethons) {
        // this.$emit(
        //   "handleClickAdd",
        //   nRow,
        //   JSON.parse(JSON.stringify(this.tableConfig.data))
        // );
        this.tableSetting.addMethons(nRow, this.tableConfig.data);
      } else {
        //如果没有外部新增方法，则新增一行
        this.tableConfig.data.push(nRow);
      }
    },
    //点击编辑
    edit() {
      let selectRow = this.$refs.editTable.selection;
      if (!selectRow.length) {
        this.$message.warning("请选择要操作的数据");
        return;
      }
      let seleteInput = this.tableConfig.column.filter(
        (i) => i.type == "select" && i.multiple
      );
      seleteInput = seleteInput.map((i) => i.prop);

      selectRow.map((i) => {
        this.tableConfig.data.map((j, index) => {
          if (i.rowIndex == j.rowIndex) {
            j.editable = true;
            seleteInput.map((k) => {
              if (!Array.isArray(j[k])) {
                j[k] = j[k] ? j[k].split(",") : [];
              }
            });
            this.$set(this.tableConfig.data, index, j);
          }
        });
      });
    },
    //点击删除
    async delete() {
      try {
        let selectRow = this.$refs.editTable.selection;
        if (!selectRow.length) {
          this.$message.warning("请选择要操作的数据");
          return;
        }
        if (this.tableSetting.hasOwnProperty("deleteMethods")) {
          let res = await this.tableSetting.deleteMethods(selectRow);
        }
        this.tableConfig.data = [...this.tableConfig.data].filter((x) =>
          [...selectRow].every((y) => y.rowIndex !== x.rowIndex)
        );
      } catch (error) {
        console.log(error);
      }
    },
    //单项删除
    async deleteItiem(data) {
      try {
        let selectRow = data;
        if (this.tableSetting.hasOwnProperty("deleteMethods")) {
          let res = await this.tableSetting.deleteMethods(selectRow);
        }
        this.tableConfig.data = [...this.tableConfig.data].filter(
          (x) => selectRow !== x.rowIndex
        );
      } catch (error) {
        console.log(error);
      }
    },
    //点击保存
    save() {
      this.$refs.formTable.validate((valid) => {
        if (valid) {
          let { data } = this.tableConfig;
          data = JSON.parse(JSON.stringify(data));
          data.forEach((i) => {
            delete i.rowIndex;
            delete i.editable;
          });
          this.$emit("save", data);
        } else {
          this.$message.error("列表资料未填写完整！");
        }
      });
    },
    //返回表单数据
    getFormData() {
      let { data } = this.tableConfig;
      // data.forEach(i => {
      //   delete i.rowIndex;
      //   delete i.editable;
      // });
      return data;
    },
    //返回表格数据
    getTableData(needValid = true) {
      return new Promise((resolve, reject) => {
        let { data } = this.tableConfig;
        data = JSON.parse(JSON.stringify(data));
        data.forEach((i) => {
          delete i.rowIndex;
          delete i.editable;
        });
        if (!needValid) {
          resolve(data);
          return;
        }
        this.$refs.formTable.validate((valid) => {
          if (valid) {
            resolve(data);
          } else {
            reject("列表未填写完整");
          }
        });
      });
    },
    //设置表单数据
    setTableData(data) {
      data = JSON.parse(JSON.stringify(data));
      data.map((i, index) => (i.rowIndex = index));
      this.$set(this.tableConfig, "data", [...data]);
    },
    //追加data
    pushData(data) {
      let arr = [...data];
      arr.map((i) => {
        this.tableConfig.data.push(i);
      });
    },
    //下拉框选择
    changeSelete(val, text, index, option) {
      if (text) {
        let type = typeof val;
        let valText = "";
        let arr = [];
        if (type == "string") {
          arr = option.filter((i) => i.value == val);
        } else {
          arr = [...option].filter((x) => [...val].some((y) => x.value == y));
        }
        if (arr) {
          arr = arr.map((i) => {
            return i.label;
          });
          valText = arr.join();
        }
        this.tableConfig.data[index][text] = valText;
      }
    },
    //获取组织树
    getOrgInfo(index, value, item) {
      this.deptItem = Object.assign({}, { _index: index }, item);

      let arr = value ? value.split(",") : [];
      let ids = this.tableConfig.data[index][item.orgIdsStr] || "";
      let idsArr = ids ? ids.split(",") : [];
      let chosedData = [];

      this.orgMemberSelect = {
        seleteType: item.seleteType,
        props: item.treeProps,
        // chosedData: chosedData,
        column: [
          {
            label: "组织",
            prop: "orgName",
          },
        ],
      };

      arr.map((i, index) => {
        let obj = {};
        obj.id = idsArr[index];
        obj[this.orgMemberSelect.column[0].prop] = arr[index];
        chosedData.push(obj);
      });

      this.orgMemberSelect.chosedData = chosedData;

      this.show = true;
    },
    //确定选择组织树
    addSeleteMember() {
      let data = this.$refs.orgMemberSelect.getSeleteData();
      let names = "";
      let ids = "";
      if (data) {
        names = data
          .map((i) => {
            return i[this.orgMemberSelect.column[0].prop];
          })
          .join();
        ids = data
          .map((i) => {
            return i.id;
          })
          .join();
      }
      let row = this.tableConfig.data[this.deptItem._index];
      row[this.deptItem.orgIdsStr] = ids;
      row[this.deptItem.prop] = names;
      this.$set(this.tableConfig.data, this.deptItem._index, row);
      this.show = false;
    },
    /**判断空值默认- */
    formatterNull(text) {
      if (text === null || text === undefined || text === "") {
        return "-";
      } else {
        return text;
      }
    },
    /**修改表格默认值 */
    setDefalutData(form) {
      this.tableConfig.data.map((i, index) => {
        let obj = Object.assign({}, i, form);
        this.$set(this.tableConfig.data, index, obj);
      });
    },
    /**禁止输入框滚动事件 */
    stopScrollFun(evt, type) {
      if (type !== "number") {
        return true;
      }
      evt = evt || window.event;
      if (evt.preventDefault) {
        // Firefox
        evt.preventDefault();
        evt.stopPropagation();
      } else {
        // IE
        evt.cancelBubble = true;
        evt.returnValue = false;
      }
      return false;
    },
    /**设置最大高度 */
    setTableHeight() {
      let { height, maxHeight, autoHeight } = this.tableSetting;
      if (!height && !maxHeight && !autoHeight) {
        let parentH = this.$refs.editTableBox.parentElement.clientHeight;
        parentH = parentH - 68;
        this.tableConfig.height = parentH < 300 ? 300 : parentH;
      }
    },
  },
};
</script>
<style lang="less" scoped>
.editTable {
  //border: 1px solid #e1e1e1;
  margin-bottom: 10px;
  .el-form-item__content {
    font-size: 12px;
    line-height: 20px;
    white-space: pre-wrap;
  }
  .el-button--primary {
    background-color: @kr-main-color;
    border-color: @kr-main-color;
  }
  /deep/.el-checkbox__inner {
    width: 20px;
    height: 20px;
  }
  .special {
    /deep/ .el-checkbox__inner::after {
      border-color: #0d60b4 !important;
    }
  }
}
.edit-table-toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 0;
}
.edit-table-toolbar__title {
  font-weight: bold;
  margin-left: 10px;
}
.table-cloumn__span--tooltip {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
</style>
